<?php

foreach (array(
	'basics', //oid index
	'users', //nickname.tolower index
	'servers', //name.tolower index
	'servers_by_numeric', //numeric index
	'callbacks',
	'events_by_time',
	'events_by_id',
	'channels', //channel name.tolower index
    'cache',
) as $index)
	$GLOBALS[$index] = array();

abstract class basic {
	public $name = '';
	private $oid = '';
	protected $__last_modified;
	public $static = array(); //will be used with __sleep
	abstract public function destruct ();
	abstract public function valid_name ($name);
	abstract public function construct(array $pars = null);
	public function __toString () {
		return "(".get_class($this).")[".$this->oid.' '.$this->name."]";
	}
	public function __last_modified() {
		return $this->last_modified;
	}
	public function oid() {
		return $this->oid;
	}
	public function tolower() {
		return strtolower($this->name);
	}
	final public function __construct($name, array $pars = null) {
		if (!$name or !is_string($name)) throw new Exception("invalid name specified");
		$this->name = $name;
		$this->__last_modified = time();
		global $basics, $config;
		do {
			if (isset($pars['oid'])) {
				$this->oid = $pars['oid'];
				unset($pars['oid']);
			} else {
				$this->oid = uniqid(sprintf('%03u',$config->my_numeric()));
			}
		} while(array_key_exists($this->oid, $basics));
		$this->construct($pars);
		$basics[$this->oid] =& $this;
	}
	public function __set ( $name, $value ) {
		if (isset($this->{$name}) and $value === $this->{name}) return;
		$this->__last_modified = time();
		$this->{$name} = $value;
	}
}

abstract class module {
	public $name = '';
	public function __toString () {
		return "(".get_class($this).")[".$this->name."]";
	}
}

class words {
    protected $content;
    public function __construct($content) {
        if (!is_string($content))
            throw new exception("content not string");
        $this->content = $content;
    }
    public function __toString() {
        return $content;
    }
    public function first() {
        $res = strpos($this->content, ' ');
        if ($res === false)
            return $this->content;
        return substr($this->content, 0, $res);
    }
    public function &next() {
        $res = strpos($this->content, ' ');
        if ($res === false) {
            $this->content = null;
            return false;
        }
        $this->content = substr($this->content, $res + 1);
        return $this;
    }
}
abstract class stream {
    public $stream;
    public function __construct($stream) {
        if (!is_resource($stream))
            throw new exception("invalid stream");
        $this->stream =& $stream;
    }
    public function &get() {
        return $this->stream;
    }
}

function firstword($string, &$more = '') {
	$res = strpos($string, ' ');
	if ($res === false)
		return $string;
	$more = substr($string, $res + 1);
	return substr($string, 0, $res);
}
function &firstarr($arr) {
	$ret = array_values($arr);
	return $ret[0];
}
?>